﻿#define _CRT_SECURE_NO_WARNINGS 1

#include <cassert>
#include <iostream>
#include <list>
#include <map>
#include <vector>
#include <functional>
using namespace std;

int func() { return 1314; }

void test1() // 引用的基本使用场景
{
	// 下面的'='左侧的都是左值~
	int* p = new int(0);
	int a = 3;
	double c = 8;
	*p = 10;
	string s("111111");
	s[0] = 'x';

	// 左值引用左值 ( (type&):左值引用,可引用右值,const 引用也可引用右值 )
	int*& lv1 = p;
	double& lv3 = c;
	string& lv4 = s;
	int& lv5 = a;

	// const 左值引用 右值
	const int& c_lv1 = 3;
	const int& c_lv2 = a + 3;
	const int& c_rv3 = (int)c;
	const int& c_rv4 = func();
	const string& c_rv5 = string();

	// 右值引用右值 ( (type&&):右值引用,可引用右值和move后的左值 )
	int&& rv1 = 3; // 常量
	int&& rv2 = a + 3; // 表达式求值 -> 的临时对象
	int&& rv3 = (int)c; // 类型转换 -> 的临时对象
	int&& rv4 = func(); // 传值返回 -> 的临时对象
	string&& rv5 = string(); // 匿名对象

	// 右值引用move(左值)
	int*&& m_rv1 = move(p);
	int&& m_rv3 = move(c);
	string&& m_rv4 = move(s);
	int&& m_rv5 = move(a);
}

void test2() // 针对 const 左值 的引用
{
	const string a = "苏苏要精通C++"; // 在C++中，对一个变量加上const，表示变量a不可被修改

	// string& ref_lv_a = a; a会通过引用修改，编译器报错,
	const string& ref_lv_a = a;

	//	那右值引用如何 绑定 const左值 呢?
	//	const string&& ref_rv_a = move(a); -> 这里会有一个警告不会对常量变量使用move
	//	既然是一个常量了，那能不能这样写呢？
	//	const string&& ref_rv_a1 = a; 
	//	a的类型是左值，把一个左值绑定给右值引用是错误的。

	// 总结：用const左值引用去绑定const 左值
	// 理解：根据右值和移动语义的理解，右值一般是临时对象和匿名对象，或者是一些将亡值(准备销毁的左值)
	// 而移动语义呢，是对右值进行资源的窃取,而针对常量，进行拷贝或者对其进行移动语义其差别并不大~
	// 而针对const 左值,其对象所指资源不能更改，也就没有窃取的实际意义 /
	// 也就能够理解move(a)的警告：不要对常量变量进行move，没有意义;

	// 如数字常量3，常量字符串"122333415"，这些常量进行右值引用和移动语义也是没有意义~
	// 总结：用const左值引用去绑定const 对象

	// 那 const auto&& 有实际意义吗？
}

void test3() // 验证：左值引用的引用名，右值引用的引用名都被认为左值
{
	int a = 3, b = 4;
	double c = 13.14;

	int& lv1 = a;
	int& lv2 = b;
	double& lv3 = c;

	int&& rv1 = 3;
	int&& rv2 = a + b;
	int&& rv3 = (int)c;

	// 左值与右值的区别是能否取地址~
	cout << &lv1 << endl;
	cout << &lv2 << endl;
	cout << &lv3 << endl;
	cout << &rv1 << endl;
	cout << &rv2 << endl;
	cout << &rv3 << endl;
}

class myclass
{
public:
	myclass()
	{
		cout << "myclass()" << endl;
	}
	~myclass()
	{
		cout << "~myclass()" << endl;
	}
};
//myclass&& ref3 = myclass();
void test4() // 引用延长生命周期~
{
	myclass(); // 匿名对象,生命周期只在这一行~
	cout << "*****************************" << endl;
	myclass&& ref1 = myclass();
	const myclass& ref2 = myclass(); // 引用可以延长生命周期~
	cout << "*****************************" << endl;
}
//int main()
//{
//	test4();
//	cout << "*****************************" << endl;
//	return 0;
//}

void Func(string& val) // 接受普通左值
{
	cout << "void Func(string& val)" << endl;
}
void Func(const string& val) // 接受const 左值
{
	cout << "void Func(const string& val)" << endl;
}
void Func(string&& val) // 接受右值
{
	cout << "void Func(string&& val)" << endl;
}

//int main()
//{
//	string s1; // 普通左值对象
//	const string s2; // const左值对象
//	// string() 右值对象
//
//	Func(s1);
//	Func(s2);
//	Func(move(s1));
//	Func(string());
//
//	return 0;
//}

//template<class T>
//void func(T&& x)
//{
//	T x1 = x; // T是type
//	x1 += "-ZMH";
//	cout << "x" << x << endl;
//	cout << "x1" << x1 << endl;
//	cout << "若x与x1输出结果相同,则T&&为左值引用,反之为右值引用" << endl;
//}

//int main()
//{
//	string s1("NoOneButYou");
//	func(s1);		// 传左值(类型为type),编译器推导T的类型为type&，根据引用折叠规则：T&&是左值引用
//	string s2("NoOneButYou");
//	func(move(s2)); // 传右值(类型为type),编译器推导T的类型为type，T&&是右值引用
//	return 0;
//}
//
//void test()
//{
//	typedef int& lref;
//	typedef int&& rref;
//
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//
//	rref&& r4 = 1; // r4 的类型是 int&& —— 右值引用的右值引用
//}
//template <class T> T && forward(typename remove_reference<T>::type& arg);
//template <class T> T&& forward(typename remove_reference<T>::type&& arg);
//int main()
//{
//	ZMH::string s1("xxxxx");
//	ZMH::string s2 = s1;
//	ZMH::string s3 = ZMH::string("yyyyy");
//	ZMH::string s4 = "yyyyy";
//	ZMH::string s5 = move(s1);
//	cout << "******************************" << endl;
//	return 0;
//}

namespace ZMH
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		void swap(string& s)
		{
			::swap(_str, s._str);
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 拷贝构造" << endl;
			reserve(s._capacity);
			for (auto ch : s)
			{
				push_back(ch);
			}
		}
		string(string&& s)
		{
			cout << "string(string&& s) -- 移动构造" << endl;
			swap(s);
		}
		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 拷⻉赋值" << endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}
			return*this;
		}
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			swap(s);
			return *this;
		}
		~string()
		{
			delete[] _str;
			_str = nullptr;
		}
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				if (_str)
				{
					strcpy(tmp, _str);
					delete[] _str;
				}
				_str = tmp;
				_capacity = n;
			}
		}
		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity *
					2;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		const char* c_str() const
		{
			return _str;
		}
		size_t size() const
		{
			return _size;
		}
	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
	};
} 

string& Func1()
{
	string str; // 定义了一个局部对象str
	// ... 对str进行使用
	return str; // 传左值引用返回吧，会出现类似野指针的问题（所引用的对象已被销毁）
}
string Func2()
{
	string str; // 定义了一个局部对象str
	// ... 对str进行使用
	return str; // 传值返回吧，因为深拷贝的操作，会影响程序的性能（这很让人头疼）
}
string&& Func3()
{
	string str; // 定义了一个局部对象str
	// ... 对str进行使用
	return move(str); // 传右值引用返回吧，也解决不了问题（左值引用和右值引用在汇编层，本质还是指针）
}

class Solution {
public:
	ZMH::string addStrings(ZMH::string num1, ZMH::string num2)
	{
		string str;
		int end1 = num1.size() - 1, end2 = num2.size() - 1;
		int next = 0;
		while (end1 >= 0 || end2 >= 0)
		{
			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
			int ret = val1 + val2 + next;
			next = ret / 10;
			ret = ret % 10;
			str += ('0' + ret);
		}
		if (next == 1)
			str += '1';
		reverse(str.begin(), str.end());
		return str.c_str();
	}
};

class ll
{
public:
	ll(int a = 1,int b = 3,int c = 4)
	{
		_year = a;
		_year = b;
		_year = c;
	}
	ll& operator=(const ll& val)
	{
		swap(_year, val._year);
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{

	return 0;
}